var redis = require('redis');
var common = require('../util/common');

module.exports = function(host, port) {
    return new Handler(host, port);
};

var Handler = function(host, port) {
    this.client = redis.createClient(6379, '127.0.0.1');
    this.client.on('error', function(err) {
        console.log('Redis Error ' + err);
    });
};

var emptyFunc = function(){};

Handler.prototype.getClient = function() {
    return this.client;
};

Handler.prototype.asyncDel = function(key, cb) {
    this.client.del(key, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncDel = function(key) {
    return common.forMethod(this.client, 'del', key);
};

Handler.prototype.asyncSet = function(key, value, cb) {
    this.client.set(key, value, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncSet = function(key, value) {
    return common.forMethod(this.client, 'set', key, value);
};

Handler.prototype.asyncGet = function(key, cb) {
    this.client.get(key, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncGet = function(key) {
    return common.forMethod(this.client, 'get', key);
};

Handler.prototype.asyncSetnx = function(key, value, cb) {
    this.client.setnx(key, value, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncSetnx = function(key, value) {
    return common.forMethod(this.client, 'setnx', key, value);
};

Handler.prototype.asyncHmset = function(key, value, cb) {
    this.client.hmset(key, value, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncHmset = function(key, value) {
    return common.forMethod(this.client, 'hmset', key, value);
};

Handler.prototype.asyncHgetAll = function(key, cb) {
    this.client.hgetall(key, cb);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncHgetAll = function(key) {
    return common.forMethod(this.client, 'hgetall', key);
};

Handler.prototype.asyncHmget = function(key, fields, cb) {
    this.client.hmget(key, fields, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncHmget = function(key, fields) {
    return common.forMethod(this.client, 'hmget', key, fields);
};

Handler.prototype.asyncHset = function(key, field, value, cb) {
    this.client.hset(key, field, value, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncHset = function(key, field, value) {
    return common.forMethod(this.client, 'hset', key, field, value);
};

Handler.prototype.asyncHget = function(key, field, cb) {
    this.client.hget(key, field, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncHget = function(key, field) {
    return common.forMethod(this.client, 'hget', key, field);
};

Handler.prototype.asyncHdel = function(key, field, cb) {
    this.client.hdel(key, field, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncHdel = function(key, field) {
    return common.forMethod(this.client, 'hdel', key, field);
};

Handler.prototype.asyncHincrby = function(key, field, count, cb) {
    this.client.hincrby(key, field, count, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncHincrby = function(key, field, count) {
    return common.forMethod(this.client, 'hincrby', key, field, count);
};

Handler.prototype.asyncSadd = function(key, value, cb) {
    this.client.sadd(key, value, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncSadd = function(key, value) {
    return common.forMethod(this.client, 'sadd', key, value);
};

Handler.prototype.asyncSmembers = function(key, cb) {
    this.client.smembers(key, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncSmembers = function(key) {
    return common.forMethod(this.client, 'smembers', key);
};

Handler.prototype.asyncScard = function(key, cb) {
    this.client.scard(key, cb || emptyFunc);
}
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncScard = function(key) {
    return common.forMethod(this.client, 'scard', key);
};

Handler.prototype.asyncLpush = function(key, data, cb) {
    this.client.lpush(key, data, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncLpush = function(key, data) {
    return common.forMethod(this.client, 'lpush', key, data);
};

Handler.prototype.asyncLgetAll = function(key, cb) {
    this.client.lrange(key, 0, -1, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncLgetAll = function(key) {
    return common.forMethod(this.client, 'lrange', key, 0, -1);
};

Handler.prototype.asyncLtrim = function(key, start, end, cb) {
    this.client.ltrim(key, start, end, cb || emptyFunc);
};
/**
 * note: must called inside a fiber
 */
Handler.prototype.syncLtrim = function(key, start, end) {
    return common.forMethod(this.client, 'ltrim', key, start, end);
};